Skip to content

Conversation

@manavgup
Copy link
Owner

Summary

Fixes mock user creation failure after database wipes by correcting exception import path mismatch between service and repository layers.

Problem

Mock user was not being recreated after database wipes, causing NotFoundError: User not found: ibm_id=mock-user-ibm-id:

  • mock_auth.py was catching: core.custom_exceptions.NotFoundError
  • user_repository.py was raising: rag_solution.core.exceptions.NotFoundError
  • Different exception classes = exception never caught = silent failure
  • User creation logic never executed

Root Cause

Two exception hierarchies exist in codebase:

  1. core.custom_exceptions.* (older, deprecated)
  2. rag_solution.core.exceptions.* (current, actively used)

Repository layer uses rag_solution.core.exceptions, but service layer was using the old hierarchy.

Solution

  • ✅ Changed import in backend/core/mock_auth.py line 16
  • ✅ Now catches the correct NotFoundError class
  • ensure_mock_user_exists() properly handles user-not-found scenario

Impact

  • Mock user auto-creation works after database wipes
  • Development workflow no longer blocked
  • Exception handling aligned across service and repository layers

Files Changed

  • backend/core/mock_auth.py (line 16 - import statement)

Testing

  • ✅ Manual testing with database wipe + backend restart
  • ✅ Mock user successfully created on startup
  • ✅ No NotFoundError in logs

Type

  • Bug fix (critical)
  • New feature
  • Breaking change
  • Refactoring

🤖 Generated with Claude Code

Fixed exception import causing mock user creation to fail silently after
database wipes. Mock users would not be recreated despite code restart.

Problem:
- mock_auth.py caught: core.custom_exceptions.NotFoundError
- user_repository.py raised: rag_solution.core.exceptions.NotFoundError
- Different exception classes = never caught = silent failure
- User creation logic never executed due to unhandled exception

Solution:
- Changed import in mock_auth.py line 16:
  FROM: from core.custom_exceptions import NotFoundError
  TO:   from rag_solution.core.exceptions import NotFoundError
- Now catches the correct exception class

Root Cause:
- Two exception hierarchies in codebase:
  1. core.custom_exceptions.* (older, deprecated)
  2. rag_solution.core.exceptions.* (current, actively used)
- Repository layer uses rag_solution.core.exceptions
- Service layer must use same hierarchy

Impact:
- Mock user auto-creation now works after database wipes
- ensure_mock_user_exists() properly handles user-not-found scenario
- Development workflow no longer blocked by missing mock user

Files Changed:
- backend/core/mock_auth.py (line 16)

Testing:
- Verified with database wipe + backend restart
- Mock user successfully created on startup
- No more NotFoundError in logs

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions
Copy link
Contributor

🚀 Development Environment Options

This repository supports Dev Containers for a consistent development environment.

Option 1: GitHub Codespaces (Recommended)

Create a cloud-based development environment:

  1. Click the green Code button above
  2. Select the Codespaces tab
  3. Click Create codespace on fix/notfounderror-import-mismatch
  4. Wait 2-3 minutes for environment setup
  5. Start coding with all tools pre-configured!

Option 2: VS Code Dev Containers (Local)

Use Dev Containers on your local machine:

  1. Install Docker Desktop
  2. Install VS Code
  3. Install the Dev Containers extension
  4. Clone this PR branch locally
  5. Open in VS Code and click "Reopen in Container" when prompted

Option 3: Traditional Local Setup

Set up the development environment manually:

# Clone the repository
git clone https://github.com/manavgup/rag_modulo.git
cd rag_modulo
git checkout fix/notfounderror-import-mismatch

# Initialize development environment
make dev-init
make dev-build
make dev-up
make dev-validate

Available Commands

Once in your development environment:

make help           # Show all available commands
make dev-validate   # Validate environment setup
make test-atomic    # Run atomic tests
make test-unit      # Run unit tests
make lint          # Run linting

Services Available

When running make dev-up:


This automated message helps reviewers quickly set up the development environment.

@github-actions
Copy link
Contributor

PR Review: Fix NotFoundError Import Mismatch in mock_auth.py

Summary

This PR fixes a critical bug where mock user creation was silently failing after database wipes due to an exception import path mismatch. The fix is correct and necessary for proper exception handling alignment.


✅ Code Quality & Best Practices

Strengths

  1. Root Cause Correctly Identified: The PR properly diagnoses the issue - two different NotFoundError classes exist in the codebase:

    • core.custom_exceptions.NotFoundError (older, deprecated hierarchy)
    • rag_solution.core.exceptions.NotFoundError (current, actively used)
  2. Minimal, Surgical Change: Only 3 lines changed - exactly what's needed, nothing more. This follows the principle of minimal invasive fixes.

  3. Improved Logging: The addition of logger.debug("Mock user not found, will create new user") on line 150 provides better observability during exception handling.

  4. Exception Handling Alignment: The fix aligns with repository layer conventions. From user_repository.py:76:

    raise NotFoundError("User", identifier=f"ibm_id={ibm_id}")

    This now matches the import in mock_auth.py:16.


🔍 Potential Issues

1. Test Coverage Missing ⚠️

Severity: Medium

No unit tests exist specifically for ensure_mock_user_exists() function. This critical authentication flow should have test coverage for:

# Recommended test cases:
def test_ensure_mock_user_exists_creates_new_user_when_not_found()
def test_ensure_mock_user_exists_returns_existing_user_when_found()
def test_ensure_mock_user_exists_handles_repository_errors()
def test_ensure_mock_user_exists_falls_back_to_identity_service()

Location: backend/tests/unit/test_mock_auth.py (should be created)

Recommendation: Add unit tests to prevent regression and validate the exception handling behavior.


2. Technical Debt: Dual Exception Hierarchies 🏗️

Severity: Medium

The codebase has two exception hierarchies coexisting:

Old hierarchy (core/custom_exceptions.py):

  • BaseCustomError base class
  • Includes status_code and HTTP-centric design
  • Has to_dict() method for HTTP responses

New hierarchy (rag_solution/core/exceptions.py):

  • DomainError base class
  • Domain-driven design (better separation of concerns)
  • No HTTP coupling in domain layer

Files still using old hierarchy:

# Found 53 files importing from core.custom_exceptions
# Examples:
- backend/rag_solution/repository/user_repository.py (line 7)
- backend/rag_solution/services/question_service.py
- backend/rag_solution/generation/providers/*.py

Recommendation:

  • Create a migration plan to consolidate on rag_solution.core.exceptions
  • Add deprecation warnings to core.custom_exceptions
  • Consider this as follow-up work (separate issue)

3. Exception Handling Could Be More Specific 🎯

Severity: Low

Current code (line 148):

except (NotFoundError, ValueError, AttributeError, TypeError):

Issue: Catching generic exceptions like ValueError, AttributeError, and TypeError masks potential programming errors. These should ideally fail loudly during development.

Recommendation:

except NotFoundError:
    # User doesn't exist, proceed to create
    logger.debug("Mock user not found, will create new user")
except (ValueError, AttributeError, TypeError) as e:
    # Log unexpected errors more prominently
    logger.warning(f"Unexpected error checking for mock user: {e}", exc_info=True)
    # Let it fall through to creation logic

This provides better debugging when unexpected errors occur.


🔒 Security Considerations

✅ No Security Issues Detected

  • The change doesn't introduce any new security vulnerabilities
  • Mock authentication is correctly gated by SKIP_AUTH environment variable
  • The fallback mechanism to IdentityService.get_mock_user_id() on line 169 provides safe degradation

⚡ Performance Considerations

✅ No Performance Impact

  • Exception handling change has negligible performance impact
  • The function is only called during startup/initialization
  • No database query changes

📝 Documentation & Logging

Strengths

  1. PR Description is Excellent: Clear problem statement, root cause analysis, and impact assessment
  2. Code Comments: Function docstring at line 110-130 is comprehensive

Suggestions

  1. Document Exception Hierarchy Migration: Add a note to CLAUDE.md or docs/development/contributing.md about which exception hierarchy to use:

    ## Exception Handling
    
    **IMPORTANT**: Use `rag_solution.core.exceptions.*` for all new code.
    The old `core.custom_exceptions.*` hierarchy is deprecated.
  2. Add Comment at Import: Consider adding a comment at line 16 to prevent future confusion:

    # Use rag_solution.core.exceptions (not core.custom_exceptions) to match repository layer
    from rag_solution.core.exceptions import NotFoundError

🧪 Testing Recommendations

Manual Testing

Verified by PR author: Database wipe + backend restart works

Automated Testing Needed

Create backend/tests/unit/test_mock_auth.py:

import pytest
from unittest.mock import Mock, patch
from uuid import uuid4
from rag_solution.core.exceptions import NotFoundError
from core.mock_auth import ensure_mock_user_exists

def test_ensure_mock_user_exists_catches_correct_exception():
    """Verify that the correct NotFoundError is caught."""
    mock_db = Mock()
    mock_settings = Mock(
        mock_user_email="test@example.com",
        mock_user_name="Test User"
    )
    
    with patch('core.mock_auth.UserService') as mock_service:
        # Simulate repository raising NotFoundError
        mock_repo = Mock()
        mock_repo.get_by_ibm_id.side_effect = NotFoundError(
            "User", identifier="ibm_id=mock-user-ibm-id"
        )
        mock_service.return_value.user_repository = mock_repo
        
        # Mock successful user creation
        mock_user = Mock(id=uuid4())
        mock_service.return_value.create_user.return_value = mock_user
        
        # Should not raise - exception should be caught
        user_id = ensure_mock_user_exists(mock_db, mock_settings)
        
        # Verify user creation was called
        assert mock_service.return_value.create_user.called

📊 Impact Assessment

Before This Fix

  • ❌ Mock users not created after DB wipes
  • ❌ Silent failures (NotFoundError uncaught)
  • ❌ Development workflow blocked
  • ❌ Confusing error messages

After This Fix

  • ✅ Mock users auto-created correctly
  • ✅ Exceptions handled properly
  • ✅ Development workflow unblocked
  • ✅ Clear debugging logs

🎯 Final Recommendation

APPROVE with Minor Suggestions

This PR should be merged as it fixes a critical bug. However, I recommend:

  1. Before Merge (Optional but recommended):

    • Add basic unit test for ensure_mock_user_exists()
  2. Follow-up Issues (Can be done after merge):

    • Create issue: "Consolidate exception hierarchies across codebase"
    • Create issue: "Add comprehensive test coverage for mock authentication"
    • Update documentation about which exception hierarchy to use

📚 References

  • Exception hierarchy: backend/rag_solution/core/exceptions.py:20-38
  • Repository usage: backend/rag_solution/repository/user_repository.py:66-82
  • Related docs: docs/features/authentication-bypass.md

Great work on the detailed root cause analysis! The PR description is exemplary - it clearly explains the problem, root cause, and solution. 🎉

@manavgup manavgup merged commit 412ec1a into main Oct 25, 2025
23 of 24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants